package org.brownflat.dbinit.upgrade;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>Database Init &copy Rupert Jones 2013</p>
 *
 * @author rup
 */
public class FileUpgradeSource extends AbstractUpgradeSource {
    private static final String PATTERN = "(patch-)(\\d*)_(.*)(.sql)";
    private String path;
    private Upgrade initial = new DummyZeroUpgrade();
    private UpgradeFinder upgradeFinder;

    public FileUpgradeSource(String path, UpgradeFinder finder) {
        this.path = path;
        this.upgradeFinder = finder;
    }

    @Override
    public List<Upgrade> getUpgrades() {
        List<Upgrade> upgrades = new ArrayList<Upgrade>();
        try {
            File[] files = (File[]) upgradeFinder.find(path, PATTERN);
            for(File file : files) {
                String content = parseContent(file);
                String name = parseName(file);
                int sequence = parseSequence(file);
                upgrades.add(new DefaultUpgrade(sequence, content, name));
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        upgrades.add(initial);
        sort(upgrades);
        return upgrades;
    }

    @Override
    public void setInitialUpgrade(Upgrade initial) {
        this.initial = initial;
    }

    private int parseSequence(File file) {
        Pattern compiledPattern = Pattern.compile(PATTERN);
        Matcher matcher = compiledPattern.matcher(file.getName());
        boolean matchFound = matcher.find();

        if(matchFound) {
            String sequenceString = matcher.group(2);
            return Integer.parseInt(sequenceString);
        } else {
            throw new RuntimeException("Could not find sequence number in file name " + file.getName());
        }
    }

    private String parseName(File file) {
        Pattern compiledPattern = Pattern.compile(PATTERN);
        Matcher matcher = compiledPattern.matcher(file.getName());
        boolean matchFound = matcher.find();

        if(matchFound) {
            String name = matcher.group(3);
            return name;
        } else {
            throw new RuntimeException("Could not find sequence number in file name " + file.getName());
        }
    }

    private String parseContent(File file) {
        StringBuilder contents = new StringBuilder();
        try {
            BufferedReader input =  new BufferedReader(new FileReader(file));
            String line = null;
            while (( line = input.readLine()) != null){
              contents.append(line);
              contents.append(System.getProperty("line.separator"));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return contents.toString();
    }
}
